package com.example.myproject.redis.redission.service;

import com.github.utils.DateUtils;
import org.redisson.RedissonRedLock;
import org.redisson.api.RLock;
import org.redisson.api.RLockRx;
import org.redisson.api.RedissonClient;
import org.redisson.api.RedissonRxClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.concurrent.TimeUnit;

@Service
public class RedLockService {

    private Logger logger = LoggerFactory.getLogger(RedLockService.class);

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private RedissonClient redissonClient2;


    @Autowired
    private RedissonClient redissonClient3;

    //redlock问题

    //@SuppressWarnings("squid:S2222")
    public RLock getLock1ByDataUuid(String dataUuid) {
        RLock rLock = redissonClient.getLock(getLockName(dataUuid));
        return  rLock;
    }

    public RLock tryLock(String dataUuid,long waitEsInSeconds,long releaseInSeconds) {
        String tag = Thread.currentThread().getName()+",multiLockCommon:";
        RLock lock1 = redissonClient.getLock(getLockName(dataUuid));
        RLock lock2 = redissonClient2.getLock(getLockName(dataUuid));
        RLock lock3 = redissonClient3.getLock(getLockName(dataUuid));
        RLock multiLock = new RedissonRedLock(lock1, lock2, lock3);
        boolean flag = false;
        try {
            flag = multiLock.tryLock(waitEsInSeconds,releaseInSeconds, TimeUnit.SECONDS);
            if (!flag) {
                logger.warn("tag;{} The getLock fail!!! dataUuid:{}", tag,dataUuid);
                //throw new BusinessException();
            }else{
                logger.info("tag;{} The getLock true!!! dataUuid:{}",tag,dataUuid);
            }
        } catch (InterruptedException e) {
            logger.error("The multiLockCommon error!!! dataUuid-:{} ", dataUuid);
            //throw new BusinessException(CommonResponseCode.RC_EXCEPTION_ERROR.getResponseCode(), CommonResponseCode.RC_EXCEPTION_ERROR.getResponseMessage());
        }
        return  multiLock;
    }



    //Code example of RxJava3 interface usage:  15.4

//    public void multiLockByRxJava3(String dataUuid,long wait,long releaseTime){
//        String tag = Thread.currentThread().getName();
//        RedissonRxClient anyRedisson =  redissonClient.rxJava();
//        RLock lock1 = redissonClient.getLock(getLockName(dataUuid));
//        RLock lock2 = redissonClient2.getLock(getLockName(dataUuid));
//        RLock lock3 = redissonClient3.getLock(getLockName(dataUuid));
//
//        RLockRx multiLock = anyRedisson.getMultiLock(lock1, lock2, lock3);
//
//        logger.info("multiLock tag：{}，time:{}",tag, DateUtils.date2Str(new Date(),DateUtils.DATE_FORMAT_MSEC));
//        Single<Boolean> lockRes = multiLock.tryLock(wait, releaseTime, TimeUnit.SECONDS);
//
//        Boolean flag = lockRes.blockingGet();
//        if(flag){
//            lockRes.doOnSuccess(res -> {
//                logger.warn("multiLock tag:{},Success dataUuid:{}",tag, dataUuid);
//             })
//             .doFinally(new Action() {
//                 @Override
//                 public void run() throws Throwable {
//                     multiLock.unlock();
//                 }
//             })
//            .subscribe();
//        }else{
//            logger.warn("multiLock tag:{},The getLock fail!!! dataUuid:{}",tag, dataUuid);
//        }
//    }


    public String getLockName(String dataUuid) {
        return "score_lock_key_"+dataUuid;
    }

}
